#pragma(once)

#include <iostream>
#include <queue>
#include <list>
#include <deque>
#include <memory>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>

using namespace std;
namespace learn
{
  namespace templateTest
  {

    void templateTest(void);

    // 函数模板
    template <typename T>
    inline T const &Max(T const &a, T const &b)
    {
      return a < b ? b : a;
    }

    // 函数模板,可以定义多个泛型变量
    template <typename T, typename R>
    inline T const &Max(T const &a, R const &b)
    {
      return a < reinterpret_cast<T const &>(b) ? reinterpret_cast<T const &>(b) : a;
    }

    // 类模板
    template <class T>
    class Stack
    {
    private:
      vector<T> elems; // 元素

    public:
      void push(T const &); // 入栈
      void pop();           // 出栈
      T top() const;        // 返回栈顶元素
      bool empty() const
      { // 如果为空则返回真。
        return elems.empty();
      }
      friend void templateTest(void);
    };

  }


template<typename... EnumValues>
class EnumVariable {
public:
    EnumVariable(EnumValues... values) : validValues_{values...} {}

    void Set(int value) {
        if (IsValidValue(value)) {
            value_ = value;
        }
    }

    int Get() const {
        return value_;
    }

private:
    bool IsValidValue(int value) const {
        for (const auto& validValue : validValues_) {
            if (value == validValue) {
                return true;
            }
        }
        return false;
    }

    std::vector<int> validValues_;
    int value_;
};

}